//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#include <buola/image.h>

#include <buola/image/cgc.h>
#include <buola/image/cimage.h>
#include <buola/utility/cregion.h>
#include <buola/image/ctextlayout.h>

namespace buola { namespace img {

CGC::CGC()
{
    InitState();
}

CGC::~CGC()
{
}

void CGC::ResetState()
{
    InitState();
    DoResetClip();
}

void CGC::InitState()
{
    mSource.SetSolid(CColor(0.0,0.0,0.0));
    mOp=ECompOp::OVER;
    mStroke.mCap=ELineCap::BUTT;
    mStroke.mJoin=ELineJoin::BEVEL;
    mStroke.mWidth=1.0;
}

void CGC::SetStockFont(const std::wstring &i)
{
    SetFont(CFont::GetStock(i));
}

void CGC::Translate(const CPoint_d &pT)
{
    mTransform.Translate(pT);
}

void CGC::Rotate(double pAngle)
{
    mTransform.Rotate(pAngle);
}

void CGC::Scale(double pS)
{
    mTransform.Scale(pS);
}

void CGC::Scale(const CSize_d &pS)
{
    mTransform.Scale(pS);
}

void CGC::RotateAround(const CPoint_d &pCenter,double pAngle)
{
    Translate(pCenter);
    Rotate(pAngle);
    Translate(-pCenter);
}

void CGC::Transform(const mat::C2DTransform &pT)
{
    mTransform*=pT;
}

void CGC::DrawText(const CPoint_d &pPos,const std::wstring &pText,
                            ETextPos pPosRef)
{
    CTextLayout lLayout(pText);
    lLayout.SetDefaultFont(mFont);
    lLayout.Draw(pPos,this,pPosRef);
}

CSize_d CGC::GetTextExtents(const std::wstring &pText)
{
    CTextLayout lLayout(pText);
    lLayout.SetDefaultFont(mFont);
    return lLayout.GetSize();
}

void CGC::DrawImage(const CPoint_d &pPos,const CPicture &pPixmap)
{
    Composite(pPos,pPixmap.Size(),pPixmap);
}

void CGC::DrawImageRect(const CRect_d &pSrc,const CRect_d &pDst,const CPicture &pPixmap)
{
    Composite(pDst.TopLeft(),pDst.Size(),pPixmap,pSrc.TopLeft(),pSrc.Size(),CPicture(),
              nZero,nUndefined,EExtend::NORMAL);
}

void CGC::DrawImageRectTiled(const CRect_d &pPart,const CRect_d &pRect,const CPoint_d &pOrigin,const CPicture &pPixmap)
{
    CPoint_d lDest,lSrc;
    CSize_d lSize;

    lDest.y=pRect.t;

    while(lDest.y<pRect.b)
    {
        lDest.x=pRect.l;
        lSrc.y=(((int)(lDest.y-pOrigin.y))%(int)pPart.Size().y)+pPart.t;
        lSize.y=min(pRect.b-lDest.y,pPart.Size().y);

        while(lDest.x<pRect.r)
        {
            lSrc.x=(((int)(lDest.x-pOrigin.x))%(int)pPart.Size().x)+pPart.l;
            lSize.x=min(pRect.r-lDest.x,pPart.Size().x);

            Composite(lDest,lSize,pPixmap);

            lDest.x+=lSize.x;
        }

        lDest.y+=lSize.y;
    }
}

void CGC::DrawImageScaled(const CPoint_d &pP,const CSize_d &pS,const CPicture &pPixmap)
{
    Composite(pP,pS,pPixmap,nZero,pPixmap.Size());
}

void CGC::DrawImagePart(const CRect_d &pPart,const CPoint_d &pPos,const CPicture &pPixmap)
{
    Composite(pPos,pPart.Size(),pPixmap,pPart.TopLeft(),pPart.Size(),CPicture(),nZero,nUndefined,EExtend::NORMAL);
}

void CGC::DrawImageCentered(const CRect_d &pRect,const CPicture &pPixmap)
{
    DrawImage(CPoint_d((pRect.l+pRect.r)/2-pPixmap.Size().x/2,(pRect.t+pRect.b)/2-pPixmap.Size().y/2),pPixmap);
}

void CGC::DrawImageTiled(const CRect_d &pRect,const CPoint_d &pOrigin,const CPicture &pPixmap)
{
    DrawImageRect(CRect_d(pRect.TopLeft()-pOrigin,pRect.Size()),pRect,pPixmap);
}

/*namespace img*/ } /*namespace buola*/ }
